﻿using System;
using System.Collections.Generic;
using System.Text;
using UtilityLibrary.Serialize;
using System.Xml.Serialization;

namespace Diablo3.Engine
{
    /// <summary>
    /// 职业
    /// </summary>
    public abstract class Classes
    {
        private SerializableDictionary<ItemsType, Items> _classesItems;
        public SerializableDictionary<ItemsType, Items> ClassesItems
        {
            get
            {
                return _classesItems;
            }
            set
            {
                _classesItems = value;
            }
        }

        public Classes()
        {
            Lavel = 60;
            _classesItems = new SerializableDictionary<ItemsType, Items>();
        }

        public Classes Clone()
        {
            Classes returnValue = null;

            Type t = this.GetType();
            switch (t.Name)
            {
                case "Barbarian":
                    returnValue = new Barbarian();
                    break;
                case "Wizard":
                    returnValue = new Wizard();
                    break;
                case "Monk":
                    returnValue = new Monk();
                    break;
                case "DemonHunter":
                    returnValue = new DemonHunter();
                    break;
                case "WitchDoctor":
                    returnValue = new WitchDoctor();
                    break;
                default:
                    return null;
            }

            foreach (ItemsType type in _classesItems.Keys)
            {
                returnValue.ClassesItems.Add(type, _classesItems[type]);
            }

            return returnValue;
        }

        /// <summary>
        /// 等级
        /// </summary>
        public Int32 Lavel { get; set; }

        /// <summary>
        /// 基础力量值
        /// </summary>
        protected abstract Double BaseStrength { get; }

        /// <summary>
        /// 基础敏捷值
        /// </summary>
        protected abstract Double BaseDexterity { get; }

        /// <summary>
        /// 基础智力值
        /// </summary>
        protected abstract Double BaseIntelligence { get; }

        /// <summary>
        /// 基础活力值
        /// </summary>
        protected abstract Double BaseVitality { get; }

        /// <summary>
        /// 角色基础减伤
        /// </summary>
        protected abstract Double BaseDamageReduction { get; }

        /// <summary>
        /// 基础最小伤害
        /// </summary>
        protected virtual Double BaseMinDamage { get { return 1; } }

        /// <summary>
        /// 基础攻击力范围
        /// </summary>
        protected virtual Double BaseDamageRange { get { return 3; } }

        /// <summary>
        /// 角色主属性值
        /// </summary>
        public abstract Double MainProperty { get; }

        /// <summary>
        /// 力量
        /// </summary>
        public Double Strength
        {
            get
            {
                Double returnValue = BaseStrength;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteStrength iaffecte = _classesItems[itemType] as IAffecteStrength;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 敏捷
        /// </summary>
        public Double Dexterity
        {
            get
            {
                Double returnValue = BaseDexterity;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteDexterity iaffecte = _classesItems[itemType] as IAffecteDexterity;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 智力
        /// </summary>
        public Double Intelligence
        {
            get
            {
                Double returnValue = BaseIntelligence;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteIntelligence iaffecte = _classesItems[itemType] as IAffecteIntelligence;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 活力
        /// </summary>
        public Double Vitality
        {
            get
            {
                Double returnValue = BaseVitality;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteVitality iaffecte = _classesItems[itemType] as IAffecteVitality;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 生命加成%
        /// </summary>
        public Double LifePercent
        {
            get
            {
                Double returnValue = 0;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteLifePercent iaffecte = _classesItems[itemType] as IAffecteLifePercent;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }

        /// <summary>
        /// 生命值
        /// </summary>
        public Double Life
        {
            get
            {
                return (Vitality * 35 + 276) * (1 + LifePercent);
            }
        }

        /// <summary>
        /// 护甲值
        /// </summary>
        public Double Armor
        {
            get
            {
                Double returnValue = Strength;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteArmor iaffecte = _classesItems[itemType] as IAffecteArmor;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 护甲减伤
        /// </summary>
        public Double DamageReductionByArmor
        {
            get
            {
                return Armor / (Armor + Lavel * 50);
            }
        }

        /// <summary>
        /// 物理抗性
        /// </summary>
        public Double PhysicalResistance
        {
            get
            {
                Double returnValue = Intelligence / 10;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffectePhysicalResistance iaffecte = _classesItems[itemType] as IAffectePhysicalResistance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 寒冰抗性
        /// </summary>
        public Double ColdResistance
        {
            get
            {
                Double returnValue = Intelligence / 10;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteColdResistance iaffecte = _classesItems[itemType] as IAffecteColdResistance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 火焰抗性
        /// </summary>
        public Double FireResistance
        {
            get
            {
                Double returnValue = Intelligence / 10;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteFireResistance iaffecte = _classesItems[itemType] as IAffecteFireResistance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 电击抗性
        /// </summary>
        public Double LightningResistance
        {
            get
            {
                Double returnValue = Intelligence / 10;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteLightningResistance iaffecte = _classesItems[itemType] as IAffecteLightningResistance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 毒素抗性
        /// </summary>
        public Double PoisonResistance
        {
            get
            {
                Double returnValue = Intelligence / 10;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffectePoisonResistance iaffecte = _classesItems[itemType] as IAffectePoisonResistance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 秘法/神圣抗性
        /// </summary>
        public Double ArcaneHolyResistance
        {
            get
            {
                Double returnValue = Intelligence / 10;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteArcaneHolyResistance iaffecte = _classesItems[itemType] as IAffecteArcaneHolyResistance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 抗性减伤(这里使用平均抗性带入计算公式计算)
        /// </summary>
        public Double DamageReductionByResistance
        {
            get
            {
                //取抗性平均值
                Double resistance = (PhysicalResistance + ColdResistance + FireResistance + LightningResistance + PoisonResistance + ArcaneHolyResistance) / 6;

                return resistance / (resistance + Lavel * 5);
            }
        }

        /// <summary>
        /// 闪避几率
        /// </summary>
        public Double DodgeChance
        {
            get
            {
                double dex = Dexterity;
                if (dex > 1000)
                {
                    return (dex - 1000) * 0.0001 + 0.3;
                }
                else if (dex > 500)
                {
                    return (dex - 500) * 0.0002 + 0.2;
                }
                else if (dex > 100)
                {
                    return (dex - 100) * 0.00025 + 0.1;
                }
                else
                {
                    return dex * 0.001;
                }
            }
        }

        /// <summary>
        /// 闪避减伤
        /// </summary>
        public Double DamageReductionByDodge
        {
            get
            {
                return DodgeChance;
            }
        }

        /// <summary>
        /// 远程减伤
        /// </summary>
        public Double MissileDamageReduction
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteMissileDamageReduction iaffecte = _classesItems[itemType] as IAffecteMissileDamageReduction;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }

        /// <summary>
        /// 近战减伤
        /// </summary>
        public Double MeleeDamageReduction
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteMeleeDamageReduction iaffecte = _classesItems[itemType] as IAffecteMeleeDamageReduction;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }

        /// <summary>
        /// 最大格挡值
        /// </summary>
        public Double MaxBlockValue
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteBlockValue iaffecte = _classesItems[itemType] as IAffecteBlockValue;
                    if (iaffecte != null) returnValue = iaffecte.AffecteMax(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 最小格挡值
        /// </summary>
        public Double MinBlockValue
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteBlockValue iaffecte = _classesItems[itemType] as IAffecteBlockValue;
                    if (iaffecte != null) returnValue = iaffecte.AffecteMin(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 格挡值(平均值)
        /// </summary>
        public Double BlockValue
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteBlockValue iaffecte = _classesItems[itemType] as IAffecteBlockValue;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 格挡几率
        /// </summary>
        public Double BlockChance
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteBlockChance iaffecte = _classesItems[itemType] as IAffecteBlockChance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }

        /// <summary>
        /// 总减伤
        /// </summary>
        public Double TotalDamageReduction
        {
            get
            {
                return 1 - ((1 - BaseDamageReduction) * (1 - DamageReductionByArmor) * (1 - DamageReductionByResistance) * (1 - DamageReductionByDodge) * (1 - (MissileDamageReduction + MeleeDamageReduction) / 2));
            }
        }

        /// <summary>
        /// 有效生命值
        /// </summary>
        public Double EffectiveLife
        {
            get
            {
                return Life / (1 - TotalDamageReduction) + BlockValue * BlockChance / (1 - TotalDamageReduction);
            }
        }

        /// <summary>
        /// 最小伤害值
        /// </summary>
        public Double MinDamage
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteMinDamage iaffecte = _classesItems[itemType] as IAffecteMinDamage;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 最大伤害
        /// </summary>
        public Double MaxDamage
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteMaxDamage iaffecte = _classesItems[itemType] as IAffecteMaxDamage;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 基础伤害
        /// </summary>
        public Double BaseDamage
        {
            get
            {
                //Double showDamage = 0;

                //IAffecteShowDamage iaffecteShowDamage = _classesItems[ItemsType.Weapons] as IAffecteShowDamage;
                //if (iaffecteShowDamage != null) showDamage = iaffecteShowDamage.GetShowDamage();

                ////武器基础攻速
                //Double attackSpeed = 0;
                //IAffecteAttackSpeed iaffecteAttackSpeed = _classesItems[ItemsType.Weapons] as IAffecteAttackSpeed;
                //if (iaffecteAttackSpeed != null) attackSpeed = iaffecteAttackSpeed.Affecte(attackSpeed);
                //if (attackSpeed == 0) return 1;

                ////武器攻速加成
                //Double weaponsSpeedPercent = 0;
                //IAffecteAttackSpeedPercent iaffecteAttackSpeedPercent = _classesItems[ItemsType.Weapons] as IAffecteAttackSpeedPercent;
                //if (iaffecteAttackSpeedPercent != null) weaponsSpeedPercent = iaffecteAttackSpeedPercent.Affecte(weaponsSpeedPercent);

                //attackSpeed = attackSpeed * (1 + weaponsSpeedPercent / 100);

                //return showDamage / attackSpeed + (MinDamage + MaxDamage) / 2;

                return (MinDamage + MaxDamage) / 2;
            }
        }

        /// <summary>
        /// 武器面板伤害
        /// </summary>
        public Double WeaponsShowDamage
        {
            get
            {
                Double showDamage = 0;

                IAffecteShowDamage iaffecteShowDamage = _classesItems[ItemsType.Weapons] as IAffecteShowDamage;
                if (iaffecteShowDamage != null) showDamage = iaffecteShowDamage.GetShowDamage();

                if (showDamage == 0) return 2.5;
                
                return showDamage;
            }
        }

        /// <summary>
        /// 主属性伤害加成
        /// </summary>
        public Double DamageIncreasedByMainProperty
        {
            get
            {
                return MainProperty / 100;
            }
        }

        /// <summary>
        /// 技能伤害加成
        /// </summary>
        public Double DamageIncreasedBySkills
        {
            get
            {
                return 0;
            }
        }

        public Double WeaponsAttackSpeed
        {
            get
            {
                //武器基础攻速
                Double attackSpeed = 0;
                IAffecteAttackSpeed iaffecteAttackSpeed = _classesItems[ItemsType.Weapons] as IAffecteAttackSpeed;
                if (iaffecteAttackSpeed != null) attackSpeed = iaffecteAttackSpeed.Affecte(attackSpeed);
                if (attackSpeed == 0) return 1;

                IAffecteAttackSpeedPercent iaffecteAttackSpeedPercent = _classesItems[ItemsType.Weapons] as IAffecteAttackSpeedPercent;
                if (iaffecteAttackSpeedPercent != null) attackSpeed = iaffecteAttackSpeedPercent.Affecte(attackSpeed);

                return attackSpeed;
            }
        }

        public Double ItemsAttackSpeed
        {
            get
            {
                //其他攻速加成
                Double attackSpeed = 1;
                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    if (itemType != ItemsType.Weapons)
                    {
                        IAffecteAttackSpeedPercent iaffecte = _classesItems[itemType] as IAffecteAttackSpeedPercent;
                        if (iaffecte != null) attackSpeed = iaffecte.Affecte(attackSpeed);
                    }
                }

                return attackSpeed - 1;
            }
        }

        /// <summary>
        /// 攻击速度
        /// </summary>
        public Double AttackSpeed
        {
            get
            {
                return WeaponsAttackSpeed * (1 + ItemsAttackSpeed);
            }
        }

        /// <summary>
        /// 暴击几率
        /// </summary>
        public Double CriticalHitChance
        {
            get
            {
                Double returnValue = 5;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteCriticalHitChance iaffecte = _classesItems[itemType] as IAffecteCriticalHitChance;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }

        /// <summary>
        /// 暴击伤害
        /// </summary>
        public Double CriticalHitDamage
        {
            get
            {
                Double returnValue = 50;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteCriticalHitDamage iaffecte = _classesItems[itemType] as IAffecteCriticalHitDamage;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }

        /// <summary>
        /// 人物面板伤害
        /// </summary>
        public Double Damage
        {
            get
            {
                return WeaponsShowDamage * (1 + DamageIncreasedByMainProperty) * (1 + DamageIncreasedBySkills) * (1 + ItemsAttackSpeed) * (1 + CriticalHitChance * CriticalHitDamage) + BaseDamage * (1 + DamageIncreasedByMainProperty) * (1 + DamageIncreasedBySkills) * AttackSpeed * (1 + CriticalHitChance * CriticalHitDamage);
            }
        }

        /// <summary>
        /// 击中回复
        /// </summary>
        public Double LifePerHit
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteLifePerHit iaffecte = _classesItems[itemType] as IAffecteLifePerHit;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 击杀回复
        /// </summary>
        public Double LifePerKill
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteLifePerKill iaffecte = _classesItems[itemType] as IAffecteLifePerKill;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 每秒回复
        /// </summary>
        public Double LifePerSecond
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteLifePerSecond iaffecte = _classesItems[itemType] as IAffecteLifePerSecond;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue;
            }
        }

        /// <summary>
        /// 生命汲取
        /// </summary>
        public Double LifeSteal
        {
            get
            {
                Double returnValue = 0;

                foreach (ItemsType itemType in _classesItems.Keys)
                {
                    IAffecteLifeSteal iaffecte = _classesItems[itemType] as IAffecteLifeSteal;
                    if (iaffecte != null) returnValue = iaffecte.Affecte(returnValue);
                }

                return returnValue / 100;
            }
        }
    }
}
